#include "shader.h"
#include <QDebug>
#include <QOpenGLShader>

Shader::Shader()
{
    shaderProgram = nullptr;
}

Shader::~Shader()
{
    if (shaderProgram != nullptr)
    {
        delete shaderProgram;
    }
}

GLboolean Shader::compile(const QString &vertexSource,
                          const QString &fragmentSource,
                          const QString &geometrySource)
{
    QOpenGLShader vertexShader(QOpenGLShader::Vertex);
    bool success = vertexShader.compileSourceFile(vertexSource);
    if (!success)
    {
        qDebug() << "ERROR::SHADER::VERTEX::COMPILATION_FAILED";
        qDebug() << vertexShader.log();
        return GL_FALSE;
    }

    QOpenGLShader fragmentShader(QOpenGLShader::Fragment);
    success  = fragmentShader.compileSourceFile(fragmentSource);
    if (!success)
    {
        qDebug() << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED";
        qDebug() << fragmentShader.log();
        return GL_FALSE;
    }

    QOpenGLShader geometryShader(QOpenGLShader::Geometry);
    if (geometrySource != NULL)
    {
        success  = geometryShader.compileSourceFile(geometrySource);
        if (!success)
        {
            qDebug() << "ERROR::SHADER::GEOMETRY::COMPILATION_FAILED";
            qDebug() << geometryShader.log();
            return GL_FALSE;
        }
    }

    shaderProgram = new QOpenGLShaderProgram();
    if (nullptr == shaderProgram)
    {
        return GL_FALSE;
    }

    shaderProgram->addShader(&vertexShader);
    shaderProgram->addShader(&fragmentShader);

    if (geometrySource != NULL)
    {
        shaderProgram->addShader(&geometryShader);
    }

    success = shaderProgram->link();
    if (!success)
    {
        qDebug() << "ERROR::SHADER::PROGRAM::LINKING_FAILED";
        qDebug() << shaderProgram->log();

        delete shaderProgram;
        shaderProgram = nullptr;

        return GL_FALSE;
    }

    return GL_TRUE;
}
